package com.ccsoft.multithread.test;

import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @author chanchaw
 * @create 2022-08-17 16:23
 * 演示 newFixedThreadPool
 */
@Slf4j(topic = "No5newFixedThreadPool")
public class No5newFixedThreadPool {

    static ExecutorService pp;

    // 添加关闭线程池的钩子 - jvm 会执行完该钩子下的逻辑后再关闭
    static {
        Runtime.getRuntime().addShutdownHook(new Thread(() -> shutdown(pp)));
    }

    public static void main(String[] args) {

        pp = Executors.newFixedThreadPool(4, new ThreadFactory() {
            private AtomicInteger i = new AtomicInteger(1);

            @Override
            public Thread newThread(Runnable r) {
                return new Thread(r,"ccThread" + i.getAndIncrement());
            }
        });

        pp.execute(()->{
            log.info("No1 start...");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            log.info("No1 end...");
        });

        pp.execute(()->{
            log.info("No2 start...");
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            log.info("No2 end...");
        });

        pp.execute(()->{
            log.info("No3 start...");
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            log.info("No3 end...");
        });

        log.info("主线程的逻辑走完了。。。");
    }



    // 关闭线程池的钩子函数
    private static void shutdown(ExecutorService executorService) {
        log.info("开始优雅的关闭线程池");
        // 第一步：使新任务无法提交
        executorService.shutdown();
        try {
            // 第二步：等待未完成任务结束
            if(!executorService.awaitTermination(60, TimeUnit.SECONDS)) {
                // 第三步：取消当前执行的任务
                executorService.shutdownNow();
                // 第四步：等待任务取消的响应
                if(!executorService.awaitTermination(60, TimeUnit.SECONDS)) {
                    System.err.println("Thread pool did not terminate");
                }
            }
        } catch(InterruptedException ie) {
            // 第五步：出现异常后，重新取消当前执行的任务
            executorService.shutdownNow();
            Thread.currentThread().interrupt(); // 设置本线程中断状态
        }
    }


}
